package com.twu.module1;


public class PrinterExercises {

    public void go() {
        System.out.println("Printing one asterisk");
        System.out.println(printOneAsterisk());

        System.out.println("\nPrinting a string of asterisks,length, n = 8");
        System.out.println(createLineWithSpecifiedNumberOfAsterisks(8));

        System.out.println("\nPrinting, n = 3, lines of asterisks");

        int n = 3;
        printNLinesOfAsterisks(n, "*");

        System.out.println("\nPrinting a right triangle, height n = 3");
        printRightTriangle(n);

        System.out.println("\nPrint a centered triangle, height n = 3");
        printACenteredTriangle(n);

        System.out.println("\nPrinting a diamond, top triangle height, n = 4");
        printDiamond(5);

        System.out.println("Print Diamond with Name");
        printDiamondWithName("Bill", 5);
        printDiamondWithName("Carol", 5);

        System.out.println("FizzBuzz");
        fizzBuzz();

        System.out.println("\nPrime Factors of 1");
        System.out.println(Utilities.primeFactors(1));

        System.out.println("\nPrime Factors of 30");
        System.out.println(Utilities.primeFactors(30));


    }

    private void printDiamondWithName(String name, int height) {
        /*TODO change alignment based on num characters for name
          Additional handling of names longer than base needed  */
        printACenteredTriangle(height);

        int nameLength = name.length();
        int baseWidth = height * 2 + 1;
        if (nameLength < baseWidth) {
            padWithLeadingSpaces(baseWidth, name);
        } else {
            System.out.println(name);
        }
        printDownwardCenteredTriangle(height - 1, 0);
    }

    public void padWithLeadingSpaces(int baseWidth, String name) {
        int numberToPad = (baseWidth - name.length()) / 2;
        String padded = "";
        for (int i = 0; i < numberToPad; i++) {
            padded += " ";
        }
        System.out.println(padded + name);
    }


    private void fizzBuzz() {
        for (int i = 1; i <= 100; i++) {
            if (i % 3 == 0 && i % 5 == 0) {
                System.out.println("FizzBuzz");
            } else if (i % 3 == 0) {
                System.out.println("Fizz");
            } else if (i % 5 == 0) {
                System.out.println("Buzz");
            } else {
                System.out.println(i);
            }
        }
    }

    private void printDiamond(int heightUpperTriangle) {
        printACenteredTriangle(heightUpperTriangle);
        printDownwardCenteredTriangle(heightUpperTriangle - 2, 1);
    }

    private void printDownwardCenteredTriangle(int numLines, int startSpace) {
        int numSpaces = startSpace;
        for (int i = numLines; i >= 0; i--) {
            System.out.println(createLine(i * 2 + 1, numSpaces));
            numSpaces++;
        }
    }

    private String createLine(int numStars, int spaces) {
        String line = "";
        line += numberOfSpaces(spaces);
        line += createLineWithSpecifiedNumberOfAsterisks(numStars);
        return line;
    }

    private void printACenteredTriangle(int numberOfLines) {
        int maxNumberOfAsterisks = 2 * (numberOfLines);
        int numSpaces = (maxNumberOfAsterisks) / 2 - 1;
        for (int i = 1; i <= maxNumberOfAsterisks; i = i + 2) {
            String lineToPrint = numberOfSpaces(numSpaces) + createLineWithSpecifiedNumberOfAsterisks(i);
            System.out.println(lineToPrint);
            numSpaces--;
        }
    }

    private String numberOfSpaces(int numSpaces) {
        String line = "";
        for (int i = 0; i < numSpaces; i++) {
            line += " ";
        }
        return line;
    }

    private void printRightTriangle(int numberOfLines) {
        for (int i = 1; i <= numberOfLines; i++) {
            System.out.println(createLineWithSpecifiedNumberOfAsterisks(i));
        }
    }

    private void printNLinesOfAsterisks(int numberOfLines, String lineToPrint) {
        String[] lines = printLines(lineToPrint, numberOfLines);
        for (String line : lines) {
            System.out.println(line);
        }
    }

    public static String printOneAsterisk() {
        return "*";
    }

    public static String createLineWithSpecifiedNumberOfAsterisks(int numberToPrint) {
        String line = "";
        for (int i = 0; i < numberToPrint; i++) {
            line += "*";
        }
        return line;
    }

    public static String[] printLines(String s, int numberOfLines) {
        String[] lines = new String[numberOfLines];
        for (int i = 0; i < numberOfLines; i++) {
            lines[i] = s;
        }
        return lines;
    }
}
